package com.finna.tenant.service.impl;

import com.finna.tenant.dto.*;
import com.finna.tenant.dto.TenantAccountJoinDTO.TenantAccountJoinCreateRequest;
import com.finna.tenant.dto.TenantDTO.TenantCreateRequest;
import com.finna.tenant.dto.TenantDTO.TenantListRequest;
import com.finna.tenant.dto.TenantDTO.TenantResponse;
import com.finna.tenant.dto.TenantDTO.TenantUpdateRequest;
import com.finna.tenant.entity.Tenant;
import com.finna.tenant.mapper.TenantMapper;
import com.finna.tenant.service.TenantAccountJoinService;
import com.finna.tenant.service.TenantService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 租户Service实现
 */
@Service
public class TenantServiceImpl implements TenantService {
    
    private static final Logger logger = LoggerFactory.getLogger(TenantServiceImpl.class);
    
    @Autowired
    private TenantMapper tenantMapper;
    
    @Autowired
    private TenantAccountJoinService tenantAccountJoinService;
    
    @Override
    @Transactional
    public TenantResponse create(TenantCreateRequest request, Long userId) {
        // 创建租户
        Tenant tenant = new Tenant();
        tenant.setTenantName(request.getName());
        tenant.setTenantCode(UUID.randomUUID().toString());
        tenant.setStatus(request.getStatus() != null ? request.getStatus() : 1);
        tenant.setIsAdmin(request.getIsAdmin() != null ? request.getIsAdmin() : false);
        tenant.setIsPublic(request.getIsPublic() != null ? request.getIsPublic() : false);
        tenant.setCreateTime(LocalDateTime.now());
        tenant.setUpdateTime(LocalDateTime.now());
        tenant.setCreateBy(userId);
        tenant.setUpdateBy(userId);
        tenant.setDeleted(false);
        
        tenantMapper.insert(tenant);
        logger.info("创建租户成功: id={}, name={}", tenant.getId(), tenant.getTenantName());
        
        // 创建租户账号关联
        TenantAccountJoinCreateRequest tenantAccountJoinCreateRequest = TenantAccountJoinCreateRequest.builder()
                .tenantId(tenant.getId())
                //TODO 这一步暂时使用模拟的账号
                .accountId(123456L)
                .role(request.getIsAdmin() ? "owner" : "admin")
                .roleId(97054L)
                .build();
        tenantAccountJoinService.create(tenantAccountJoinCreateRequest);
        
        return convertToResponse(tenant);
    }
    
    @Override
    @Transactional
    public TenantResponse update(Long id, TenantUpdateRequest request) {
        Tenant tenant = tenantMapper.selectById(id);
        if (tenant == null) {
            throw new RuntimeException("租户不存在");
        }
        
        if (request.getName() != null) {
            tenant.setTenantName(request.getName());
        }
        if (request.getStatus() != null) {
            tenant.setStatus(request.getStatus());
        }
        if (request.getIsAdmin() != null) {
            tenant.setIsAdmin(request.getIsAdmin());
        }
        if (request.getIsPublic() != null) {
            tenant.setIsPublic(request.getIsPublic());
        }
        tenant.setUpdateTime(LocalDateTime.now());
        
        tenantMapper.updateById(tenant);
        logger.info("修改租户成功: id={}", id);
        
        return convertToResponse(tenant);
    }
    
    @Override
    @Transactional
    public void delete(Long id) {
        Tenant tenant = tenantMapper.selectById(id);
        if (tenant == null) {
            throw new RuntimeException("租户不存在");
        }
        
        // 软删除租户
        tenantMapper.deleteById(id);
        
        // 删除租户账号关联
        tenantAccountJoinService.deleteByTenantId(id);
        
        logger.info("删除租户成功: id={}", id);
    }
    
    @Override
    public TenantResponse getById(Long id) {
        Tenant tenant = tenantMapper.selectById(id);
        if (tenant == null) {
            throw new RuntimeException("租户不存在");
        }
        return convertToResponse(tenant);
    }
    
    @Override
    public PageResponse<TenantResponse> list(TenantListRequest request) {
        // 构建查询参数
        Map<String, Object> params = new HashMap<>();
        if (request.getName() != null && !request.getName().isEmpty()) {
            params.put("name", request.getName());
        }
        if (request.getStatus() != null) {
            params.put("status", request.getStatus());
        }
        if (request.getIsAdmin() != null) {
            params.put("isAdmin", request.getIsAdmin());
        }
        if (request.getIsPublic() != null) {
            params.put("isPublic", request.getIsPublic());
        }
        
        // 分页参数
        Integer page = request.getPage() != null ? request.getPage() : 1;
        Integer pageSize = request.getPageSize() != null ? request.getPageSize() : 10;
        if (pageSize > 100) {
            pageSize = 100; // 最大页面大小限制
        }
        
        // 使用PageHelper进行分页
        PageHelper.startPage(page, pageSize);
        List<Tenant> tenants = tenantMapper.selectList(params);
        PageInfo<Tenant> pageInfo = new PageInfo<>(tenants);
        
        // 转换为响应对象
        List<TenantResponse> responses = pageInfo.getList().stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        return new PageResponse<>(responses, pageInfo.getTotal(), page, pageSize);
    }
    
    /**
     * 转换为响应对象
     */
    private TenantResponse convertToResponse(Tenant tenant) {
        TenantResponse response = new TenantResponse();
        response.setId(tenant.getId());
        response.setName(tenant.getTenantName());
        response.setTenantName(tenant.getTenantName());
        response.setTenantCode(tenant.getTenantCode());
        response.setContactPerson(tenant.getContactPerson());
        response.setContactPhone(tenant.getContactPhone());
        response.setAddress(tenant.getAddress());
        response.setStatus(tenant.getStatus());
        response.setCreatedAt(tenant.getCreateTime());
        response.setUpdatedAt(tenant.getUpdateTime());
        return response;
    }
}